package org.springblade.modules.filesys.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.unit.DataSizeUtil;
import cn.hutool.core.net.NetUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.core.util.ZipUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.tool.api.R;
import org.springblade.modules.filesys.entity.Cooperation;
import org.springblade.modules.filesys.entity.FileNode;
import org.springblade.modules.filesys.entity.Sharing;
import org.springblade.modules.filesys.service.ICooperationService;
import org.springblade.modules.filesys.service.ISharingService;
import org.springblade.modules.filesys.vo.FileUserVO;
import org.springblade.modules.system.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.List;

/**
 *
 */
@RestController
@RequestMapping("blade-filesys/feature")
@Slf4j
@Api(value = "", tags = "文件共享系统-crud接口")
public class FileFeatureOPTController {
	@Autowired
	private ISharingService sharingService;
	@Autowired
	private ICooperationService cooperationService;
	@Value("${filesys.host1}")
	private String host1;
	@Value("${filesys.host2}")
	private String host2;

	/**
	 * 详情
	 */
	@PostMapping("/fileSharing")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "文件分享功能")
	public R<String> fileSharing(@RequestParam String filePath) {
		File file = new File(filePath);
		Sharing query = new Sharing();
		query.setFilePath(filePath);
		Sharing one = sharingService.getOne(Condition.getQueryWrapper(query));
		if (one != null) {
			R<String> fail = R.fail("文件在之前已经开启分享");
			fail.setData(one.getRemarks());
			return fail;
		}
		String md5 = "";
		if (file.isDirectory()) {
			File zip = ZipUtil.zip(filePath);
			md5 = SecureUtil.md5(zip);
			boolean delete = zip.delete();
		} else {
			md5 = SecureUtil.md5(file);
		}
		String code = RandomUtil.randomString(6);
		String sharingUrl = RandomUtil.randomString(16);
		BladeUser user1 = org.springblade.core.secure.utils.SecureUtil.getUser();
		String size = DataSizeUtil.format(FileUtil.size(file));
		boolean isDirectory = FileUtil.isDirectory(file);
		Sharing sharing = new Sharing();
		sharing.setMd5(md5);
		sharing.setName(file.getName());
		sharing.setFileSize(size);
		sharing.setIsDir(isDirectory);
		sharing.setVerificationCode(code);
		sharing.setSharingPath(sharingUrl);
		sharing.setFilePath(filePath);
		sharing.setCreateUser(user1.getUserId());
		sharing.setCreateBy(user1==null?"游客":user1.getUserName());

		StringBuffer stringBuffer = new StringBuffer();
		stringBuffer.append("文件分享地址： "+host1+"/"+sharing.getSharingPath()+" \n ");
		stringBuffer.append("验证码： "+sharing.getVerificationCode());
		sharing.setRemarks(stringBuffer.toString());
		boolean save = sharingService.save(sharing);
		return R.data(stringBuffer.toString());
	}

	@PostMapping("/fileSharingForDownload")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "文件分享下载功能")
	public R fileSharingForDownload(@RequestParam String fileId, @RequestParam String code, HttpServletResponse response) throws UnsupportedEncodingException {
		Sharing entity = sharingService.getById(fileId);
		if (entity==null||!code.equals(entity.getVerificationCode())) {
			return R.fail("文件下载验证码错误");
		}
		else {
			String filePath = entity.getFilePath();
			File file = new File(filePath);
			if (file.isDirectory()) {
				File zip = ZipUtil.zip(filePath);
				fileDownload(response, zip);
				boolean delete = zip.delete();
			} else {
				fileDownload(response, file);
			}
		}
		return R.success("");
	}

	private void fileDownload(HttpServletResponse response, File file) throws UnsupportedEncodingException {
		String myFileName= URLEncoder.encode(file.getName(), "utf-8");
		response.setCharacterEncoding("UTF-8"); //设置编码字符
		response.setContentType("application/octet-stream;charset=UTF-8"); //设置下载内容类型
		response.setHeader("Content-disposition", "attachment;filename=" + myFileName);//设置下载的文件名称
		try (OutputStream out = response.getOutputStream() //创建页面返回方式为输出流，会自动弹出下载框
		) {
			FileUtil.writeToStream(file, out);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@PostMapping("/fileCooperation")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "文件协作开启功能")
	public R fileCooperation(@RequestParam String filePath) {
		File file = new File(filePath);
		String md5 = SecureUtil.md5(file);
		BladeUser user1 = org.springblade.core.secure.utils.SecureUtil.getUser();
		Cooperation query = new Cooperation();
		query.setFilePath(filePath);
		Cooperation one = cooperationService.getOne(Condition.getQueryWrapper(query));
		if (one != null) {
			return R.fail("文件已经开启协作");
		}
		String code = RandomUtil.randomString(6);
		String url = RandomUtil.randomString(16);
		Cooperation cooperation = new Cooperation();
		cooperation.setName(file.getName());
		cooperation.setMd5(md5);
		cooperation.setFilePath(filePath);
		cooperation.setFileVersion("1");
		cooperation.setVerificationCode(code);
		cooperation.setSharingPath(url);
		// CreateBy来备注是谁在操作锁定
		cooperation.setStatus(0);
		cooperation.setCreateUser(user1.getUserId());
		cooperation.setCreateBy(user1==null?"游客":user1.getUserName());
		StringBuffer stringBuffer = new StringBuffer();
		stringBuffer.append("文件协作地址： "+host2+"/"+cooperation.getSharingPath()+" \n ");
		stringBuffer.append("验证码： "+cooperation.getVerificationCode());
		cooperation.setRemarks(stringBuffer.toString());
		boolean save = cooperationService.save(cooperation);
		return R.data(stringBuffer.toString());
	}

	@PostMapping("/fileCooperationForEdit")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "文件协作编辑功能")
	public R fileCooperationForEdit(@RequestParam String fileId) {
		Cooperation data = cooperationService.getById(fileId);
		BladeUser user1 = org.springblade.core.secure.utils.SecureUtil.getUser();
		if (data.getStatus() == 1 && !data.getEditBy().equals(user1==null?"游客":user1.getUserName())) {
			return R.fail(data.getEditBy() + "正在编辑中");
		}
		data.setEditBy(user1==null?"游客":user1.getUserName());
//		if (data.getPreviousEditBy()==null|| "".equals(data.getPreviousEditBy())){
//			data.setPreviousEditBy(user1==null?"游客":user1.getUserName());
//		}
		data.setStatus(1);
		boolean b = cooperationService.saveOrUpdate(data);
		return R.status(b);
	}

	@PostMapping("/fileCooperationForSave")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "文件协作保存功能")
	public R fileCooperationForSave(@RequestParam String fileId, @RequestParam String value,@RequestParam String version) {
		Cooperation data = cooperationService.getById(fileId);
		BladeUser user1 = org.springblade.core.secure.utils.SecureUtil.getUser();
//		if (data.getStatus()!=1){
//			return R.fail("请先编辑文件内容");
//		}

		if (data.getStatus() == 1 && !data.getEditBy().equals(user1==null?"游客":user1.getUserName())) {
			return R.fail(data.getEditBy() + "正在编辑中");
		}
		//若上一个编辑者是当前用户  跳过版本判断，提高效率 偏向锁
		if (data.getPreviousEditBy()!=null  && data.getPreviousEditBy().equals(user1==null?"游客":user1.getUserName())){
		}
		else if (!version.equals(data.getFileVersion())){
			return R.fail( "文件版本不对应，请先刷新最新文件内容");
		}
		data.setStatus(0);
		data.setEditBy("无");
		data.setPreviousEditBy(user1==null?"游客":user1.getUserName());
		data.setFileVersion(String.valueOf(Integer.valueOf(data.getFileVersion())+1));
		cooperationService.saveOrUpdate(data);
		try {
			FileUtil.writeUtf8String(value, data.getFilePath());
		} catch (Exception e) {
			log.error(e.getCause().toString());
			e.printStackTrace();
			return R.fail("保存失败" + e.getMessage());
		}
		String md5 = SecureUtil.md5(new File(data.getFilePath()));
		data.setMd5(md5);
		boolean b = cooperationService.saveOrUpdate(data);
		return R.status(b);
	}
	@PostMapping("/fileCooperationForDel")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "文件协作删除功能")
	public R fileCooperationForDel(@RequestParam String fileId) {
		Cooperation data = cooperationService.getById(fileId);
		BladeUser user1 = org.springblade.core.secure.utils.SecureUtil.getUser();
		if (!(data.getCreateUser().equals(user1.getUserId()))){
			return R.fail("删除失败，不是开启文件共享的用户");
		}
		boolean b = cooperationService.removeById(fileId);
		return R.status(b);
	}
	@GetMapping("/userinfo")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "文件协作删除功能")
	public R userinfo(@RequestParam String fileId) {
		Cooperation data = cooperationService.getById(fileId);
		BladeUser user1 = org.springblade.core.secure.utils.SecureUtil.getUser();
		FileUserVO fileUserVO = new FileUserVO();
		fileUserVO.setEditUser(data.getEditBy());
		fileUserVO.setPageUser(user1==null?"游客":user1.getUserName());
		return R.data(fileUserVO);
	}
}
